package com.example.tool.ui;

import com.example.tool.function.BiConsumer;
import com.example.tool.module.ModuleInformation;
import com.example.tool.module.ModuleInputEnum;
import com.example.tool.utils.ActionToolUtil;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.ui.JBColor;
import com.intellij.uiDesigner.core.GridLayoutManager;
import com.intellij.uiDesigner.core.Spacer;
import com.intellij.util.ui.JBUI;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.awt.Color;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SwingViewWrapper extends DialogWrapper {
  private final Project project;
  private final List<HToolViewItem<?>> hToolViewItems;
  private final String tipContent;
  private BiConsumer<ModuleInputEnum, String> biConsumer;

  public SwingViewWrapper(Project project, List<HToolViewItem<?>> hToolViewItems) {
    this(project, hToolViewItems, false);
  }

  public SwingViewWrapper(Project project, List<HToolViewItem<?>> hToolViewItems, boolean init) {
    this(project, ModuleInformation.MODULE_NAME, hToolViewItems, init);
  }

  public SwingViewWrapper(Project project, String title, List<HToolViewItem<?>> hToolViewItems) {
    this(project, title, hToolViewItems, false);
  }

  public SwingViewWrapper(Project project, String title, List<HToolViewItem<?>> hToolViewItems, boolean init) {
    this(project, title, null, hToolViewItems, init);
  }

  public SwingViewWrapper(Project project, String title, String tip, List<HToolViewItem<?>> hToolViewItems) {
    this(project, title, tip, hToolViewItems, false);
  }

  public SwingViewWrapper(Project project, String title, String tip, List<HToolViewItem<?>> hToolViewItems, boolean init) {
    this(project, title, tip, false, hToolViewItems, init);
  }

  public SwingViewWrapper(Project project, String title, String tip, Boolean resizable, List<HToolViewItem<?>> hToolViewItems) {
    this(project, title, tip, resizable, hToolViewItems, false);
  }

  /**
   * 创建弹出层的布局样式，也可作用于非弹出层的布局但需要使用build方法
   * @param project        项目对象
   * @param title          标题 仅对弹出层有效
   * @param tip            显示组件下面说明内容
   * @param resizable      是否可以改变大小 仅对弹出层有效
   * @param hToolViewItems 组件元素对象
   * @param init           是否进行弹出层初始化，不初始化则为黑框没有样式
   */
  public SwingViewWrapper(Project project, String title, String tip, Boolean resizable, List<HToolViewItem<?>> hToolViewItems, boolean init) {
    super(true);
    this.project = project;
    this.hToolViewItems = hToolViewItems;
    this.tipContent = tip;
    setTitle(title);
    setSize(450, 160);
    setResizable(resizable);
    if (init) {// 用来表示是否初始化弹出框的样式
      init();
    }
  }

  @Override
  public @Nullable JComponent getPreferredFocusedComponent() {
    for (HToolViewItem<?> hToolViewItem : this.hToolViewItems) {
      boolean focus = hToolViewItem.isFocus();
      if (focus) {
        return hToolViewItem.getT();
      }
    }
    return null;
  }

  @Override
  protected @Nullable JComponent createCenterPanel() {
    return build();
  }

  public JComponent build() {
    int size = hToolViewItems.size();
    if (size != 0 || tipContent != null) {
      JPanel jPanel = new JPanel();
      jPanel.removeAll();
      jPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10));
      GridLayoutManager gridLayoutManager;
      if (tipContent != null) {
        gridLayoutManager = new GridLayoutManager(size + 2, 2);
      } else {
        gridLayoutManager = new GridLayoutManager(size + 1, 2);
      }
      jPanel.setLayout(gridLayoutManager);
      for (int i = 0; i < size; i++) {
        HToolViewItem<?> hToolViewItem = hToolViewItems.get(i);
        ModuleInputEnum title = hToolViewItem.getTitle();
        JLabel jLabel = new JLabel(title.getValue() + ": ");
        JComponent jComponent = hToolViewItem.getT();
        SwingUi.addChild(jPanel, jLabel, i, 0);
        SwingUi.addChild(jPanel, jComponent, i, 1, true);
      }
      if (tipContent != null) {
        JPanel tips = tips(tipContent);
        SwingUi.addChild(jPanel, tips, size);
        SwingUi.addChild(jPanel, new Spacer(), size + 1, 0, true);
      } else {
        SwingUi.addChild(jPanel, new Spacer(), size, 0, true);
      }
      return jPanel;
    } else {
      return tips(ModuleInformation.ILLUSTRATE);
    }
  }

  public static JPanel tips(String content) {
    return tips(ModuleInformation.TIP, content);
  }

  public static @NotNull JPanel tips(String title, String content) {
    JPanel tips = new JPanel();
    tips.setLayout(new GridLayoutManager(1, 2, JBUI.insets(10), -1, -1));
    JBColor jbColor = new JBColor(new Color(-10591639), new Color(-10591639));
    tips.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(jbColor), title));
    SwingUi.addChild(tips, new JLabel(content), 0);
    return tips;
  }

  /**
   * 添加弹出层点击确定的校验规则
   * @param biConsumer 校验规则
   */
  public void inspect(BiConsumer<ModuleInputEnum, String> biConsumer) {
    this.biConsumer = biConsumer;
  }

  @Override
  protected void doOKAction() {
    Map<ModuleInputEnum, String> values = getValues();
    try {
      for (Map.Entry<ModuleInputEnum, String> stringObjectEntry : values.entrySet()) {
        ModuleInputEnum key = stringObjectEntry.getKey();
        String value = stringObjectEntry.getValue();
        if (value == null || value.isEmpty()) {
          throw new Exception(ModuleInformation.All_INPUT);
        }
        if (biConsumer != null) {
          biConsumer.accept(key, value);
        }
      }
      super.doOKAction();
    } catch (Exception e) {
      ActionToolUtil.showNotification(project, NotificationType.ERROR, e.getMessage());
    }
  }

  public Map<ModuleInputEnum, String> getValues() {
    Map<ModuleInputEnum, String> values = new HashMap<>();
    for (HToolViewItem<?> hToolViewItem : hToolViewItems) {
      ModuleInputEnum title = hToolViewItem.getTitle();
      String value = hToolViewItem.getValue();
      values.put(title, value);
    }
    return values;
  }
}
